home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / unixlib.lha / unix / src / open.c < prev    next >
C/C++ Source or Header  |  1996-11-05  |  3KB  |  119 lines

  1. #include "amiga.h"
  2. #include "files.h"
  3. #include "amigados.h"
  4. #include <utility/tagitem.h>
  5. #include <stdarg.h>
  6. #include <fcntl.h>
  7. #include <string.h>
  8.  
  9. int __open(const char *path, int flags,...)
  10. {
  11.     int fd, acc = flags & 3, rd, wr, exists = TRUE, amode;
  12.     struct FileInfoBlock *fib;
  13.     BPTR plock, fh;
  14.     long fdflags, protection;
  15.     APTR pwindow = _us->pr_WindowPtr;
  16.  
  17.     __chkabort();
  18.  
  19.     rd = acc == O_RDONLY || acc == O_RDWR;
  20.     wr = acc == O_WRONLY || acc == O_RDWR;
  21.  
  22.     if (stricmp(path, "NIL:") == 0)
  23.     amode = -1;
  24.     else {
  25.     _us->pr_WindowPtr = (APTR) - 1;
  26.     plock = Lock(path, ACCESS_READ);
  27.     _us->pr_WindowPtr = pwindow;
  28.     if (!plock) {
  29.         int err = convert_oserr(IoErr());
  30.  
  31.         /* Devices like pipe: don't like Lock ... */
  32.         if (err == ENOENT && (flags & O_CREAT) ||
  33.         _OSERR == ERROR_ACTION_NOT_KNOWN ||
  34.         _OSERR == 0) {    /* Some devices (tape:) don't set IoErr() ... */
  35.         va_list vmode;
  36.  
  37.         exists = FALSE;
  38.         if (flags & O_CREAT) {
  39.             if (flags & 0x8000)        /* SAS C runtime called us, no mode */
  40.             amode = FIBF_EXECUTE;    /* Maybe 0 ? */
  41.             else {
  42.             va_start(vmode, flags);
  43.             amode = _make_protection(va_arg(vmode, int));
  44.             va_end(vmode);
  45.             }
  46.         } else
  47.             amode = -1;    /* Assume complete access */
  48.         } else {
  49.         errno = err;
  50.         return -1;
  51.         }
  52.     } else {        /* File already exists, play with it */
  53.         /* Get protection */
  54.         if (!((fib = AllocDosObjectTags(DOS_FIB, TAG_END)) &&
  55.           Examine(plock, fib))) {
  56.         if (fib)
  57.             FreeDosObject(DOS_FIB, fib);
  58.         ERROR;
  59.         }
  60.         amode = fib->fib_Protection;
  61.         FreeDosObject(DOS_FIB, fib);
  62.         UnLock(plock);
  63.  
  64.         /* Check access */
  65.         if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
  66.         errno = EEXIST;
  67.         return -1;
  68.         }
  69.         if ((rd && (amode & FIBF_READ) || wr && (amode & FIBF_WRITE))) {
  70.         errno = EACCES;
  71.         return -1;
  72.         }
  73.         /* Truncate files, by opening in MODE_NEWFILE, then closing it. This
  74.            allows the file to be opened in shared mode after that (READWRITE
  75.            or OLDFILE), which is consistent with the unix semantics. */
  76.         if (flags & O_TRUNC) {
  77.         BPTR tfh;
  78.  
  79.         if (tfh = Open(path, MODE_NEWFILE))
  80.             Close(tfh);
  81.         else
  82.             ERROR;
  83.         }
  84.     }
  85.     }
  86.  
  87.     if (flags & O_CREAT) {
  88.     if (!(fh = Open(path, MODE_READWRITE)))
  89.         fh = Open(path, MODE_NEWFILE); /* Devices like pipe: want this */
  90.     } else {
  91.     fh = Open(path, MODE_OLDFILE);
  92.     }
  93.     if (!fh)
  94.     ERROR;
  95.  
  96.     /* Protection is set when file is closed because OFS & FFS
  97.        don't appreciate it being done on MODE_NEWFILE files. */
  98.     if ((flags & O_TRUNC) || !exists)
  99.     protection = amode;
  100.     else
  101.     protection = -1;
  102.  
  103.     fdflags = 0;
  104.     if (rd)
  105.     fdflags |= FI_READ;
  106.     if (wr)
  107.     fdflags |= FI_WRITE;
  108.     if (flags & O_APPEND)
  109.     fdflags |= O_APPEND;
  110.  
  111.     fd = _alloc_amigafd(fh, protection, fdflags);
  112.     if (fd < 0) {
  113.     _us->pr_WindowPtr = (APTR) - 1;
  114.     Close(fh);
  115.     _us->pr_WindowPtr = pwindow;
  116.     }
  117.     return fd;
  118. }
  119.